#include "event_app.h"
#include "basic_board.h"
#include "irq_contorl.h"
/**
 * @brief 传感器事件处理回调函数
 *
 */
static void SensorEventHandlerCallback(void);

static EventHandlerTable_t SensorEventHandlerNode = {0};

#if _HALL_SENSOR_ENABLE_

/**
 * @brief 切换霍尔中断管脚电平
 *
 * @param IrqLevel - 中断管脚电平（true：高电平 false：低电平）
 */
static void HallSwitchIrqPinLevel(bool IrqLevel);

/**
 * @brief 读取霍尔管脚电平
 *
 * @return bool - 管脚电平（true：高电平 false：低电平）
 */
static bool HallGetPinLevel(void);

/**
 * @brief 获取霍尔中断标志位
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool HallGetItFlagBit(void);

/**
 * @brief 清除霍尔中断标志
 *
 */
static void HallClearItFlagBit(void);

/**
 * @brief 失能霍尔中断
 *
 */
static void HallDisableIrq(void);

/**
 * @brief 使能霍尔中断
 *
 */
static void HallEnableIrq(void);

/**
 * @brief 霍尔中断回调
 *
 * @return bool - 中断触发标识（true：触发 false：静默）
 */
static bool HallSensorIrqCallback(void);

/**
 * @brief 霍尔管脚配置
 *
 */
static void HallPinConfiguration(void);

/**
 * @brief 霍尔事件处理方法
 *
 * @return bool - 事件处理标识（true：处理 false：静默）
 */
static bool HallEventHandler(void);

static IrqControl_t HallSensorIrqContorlNode = {0};
static HallSensorBitStatus_t HallSensorBitStatus = {0};

static void HallSwitchIrqPinLevel(bool IrqLevel)
{
  HallClearItFlagBit();

#if _BOARD_TYPE_ == _9905_A_BOARD_
  (IrqLevel == true) ? GPIOA_ITModeCfg(HALL_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOA_ITModeCfg(HALL_SENSOR_PIN, GPIO_ITMode_FallEdge);
#endif
}

static bool HallGetPinLevel(void)
{
#if _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOA_ReadPortPin(HALL_SENSOR_PIN) == HALL_SENSOR_PIN)
#endif
    return true;

  return false;
}

static bool HallGetItFlagBit(void)
{
#if _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOA_ReadPortPin(HALL_SENSOR_PIN) == HALL_SENSOR_PIN)
#endif
    return true;

  return false;
}

static void HallClearItFlagBit(void)
{
#if _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOA_ClearITFlagBit(HALL_SENSOR_PIN);
#endif
}

static void HallDisableIrq(void)
{
#if _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PA_INT_EN &= ~HALL_SENSOR_PIN;
  GPIOA_ClearITFlagBit(HALL_SENSOR_PIN);
#endif
}

static void HallEnableIrq(void)
{
#if _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PA_INT_EN |= HALL_SENSOR_PIN;
  GPIOA_ClearITFlagBit(HALL_SENSOR_PIN);
#endif
}

static bool HallSensorIrqCallback(void)
{
  if (HallGetItFlagBit() == true)
  {
    HallClearItFlagBit();

    HallSensorBitStatus.HallSensorTiggerEn = true;
    return true;
  }

  return false;
}

static void HallPinConfiguration(void)
{
#if _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOA_ModeCfg(HALL_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOA_ITModeCfg(HALL_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_A_IRQn);
#endif

  PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
  AddIrqNewTable(&HallSensorIrqContorlNode, HallSensorIrqCallback);
}

static bool HallEventHandler(void)
{
  if (HallGetPinLevel() != true)
  {
    BasicWriteDoorUnlockLogFile(true);
    PRINT("[alarm]: door is not closed.\r\n");

    return true;
  }
  else
  {
    BasicWriteDoorUnlockLogFile(false);
    PRINT("[alarm]: door has returned to the default state.\r\n");
  }

  return false;
}
#endif

#if _ANTI_SKID_DETECTION_ENABLE_

/**
 * @brief 切换防撬传感器中断管脚电平
 *
 * @param IrqLevel - 中断管脚电平（true：高电平 false：低电平）
 */
static void AntiPryingSensorSwitchIrqPinLevel(bool IrqLevel);

/**
 * @brief 读取防撬传感器管脚电平
 *
 * @return bool - 管脚电平（true：高电平 false：低电平）
 */
static bool ReadAntiPryingSensorPinLevel(void);

/**
 * @brief 获取防撬传感器中断标志位
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool GetAntiPryingSensorItFlagBit(void);

/**
 * @brief 清除防撬传感器中断标志
 *
 */
static void ClearAntiPryingSensorItFlagBit(void);

/**
 * @brief 使能防撬传感器中断
 *
 */
static void EnableAntiPryingSensorIrq(void);

/**
 * @brief 失能防撬传感器中断
 *
 */
static void DiableAntiPryingIrq(void);

/**
 * @brief 防撬中断回调
 *
 * @return bool - 中断触发状态（true：触发 false：静止）
 */
static bool AntiPryingSensorIrqCallback(void);

/**
 * @brief 防撬管脚配置
 *
 */
static void AntiPryingPinConfiguration(void);

/**
 * @brief 防撬事件处理方法
 *
 * @return bool - 事件处理标识（true：处理 false：静默）
 */
static bool AntiPryingEventHandler(void);

/**
 * @brief 创建防撬提示任务
 *
 */
static void CreateAutiPickTipTask(void);

/**
 * @brief 配置防撬提示功能
 *
 * @param En - 功能配置位（true：打开 false：关闭）
 */
static void SetAutiPickAlarmTipFunctionBit(bool En);

/**
 * @brief 重置防撬警报提示时间
 *
 */
static void ResetAutiPickAlarmTipTime(void);

static TimedTable_t AutiPickTipNode = {0};
static IrqControl_t AntiPryingIrqContorlNode = {0};
static AntiPryingBitStatus_t AntiPryingBitStatus = {0};

static void AntiPryingSensorSwitchIrqPinLevel(bool IrqLevel)
{
  ClearAntiPryingSensorItFlagBit();

#if _BOARD_TYPE_ == _6681_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(ANTI_PRYING_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(ANTI_PRYING_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  (IrqLevel == true) ? GPIOA_ITModeCfg(ANTI_PRYING_PIN, GPIO_ITMode_RiseEdge) : GPIOA_ITModeCfg(ANTI_PRYING_PIN, GPIO_ITMode_FallEdge);
#endif
}

static bool ReadAntiPryingSensorPinLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  if (GPIOB_ReadPortPin(ANTI_PRYING_PIN) == ANTI_PRYING_PIN)
    return true;

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  if (GPIOA_ReadPortPin(ANTI_PRYING_PIN) == ANTI_PRYING_PIN)
    return true;
#endif

  return false;
}

static bool GetAntiPryingSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  if (GPIOB_ReadITFlagBit(ANTI_PRYING_PIN) == ANTI_PRYING_PIN)
    return true;

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  if (GPIOA_ReadITFlagBit(ANTI_PRYING_PIN) == ANTI_PRYING_PIN)
    return true;
#endif

  return false;
}

static void ClearAntiPryingSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ClearITFlagBit(ANTI_PRYING_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOA_ClearITFlagBit(ANTI_PRYING_PIN);
#endif
}

static void EnableAntiPryingSensorIrq(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  R16_PB_INT_EN |= ANTI_PRYING_PIN;
  GPIOB_ClearITFlagBit(ANTI_PRYING_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  R16_PA_INT_EN |= ANTI_PRYING_PIN;
  GPIOA_ClearITFlagBit(ANTI_PRYING_PIN);
#endif
}

static void DiableAntiPryingIrq(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  R16_PB_INT_EN &= ~ANTI_PRYING_PIN;
  GPIOB_ClearITFlagBit(ANTI_PRYING_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  R16_PA_INT_EN &= ~ANTI_PRYING_PIN;
  GPIOA_ClearITFlagBit(ANTI_PRYING_PIN);
#endif
}

static bool AntiPryingSensorIrqCallback(void)
{
  if (GetAntiPryingSensorItFlagBit() == true)
  {
    ClearAntiPryingSensorItFlagBit();

    AntiPryingBitStatus.AntiPryingTiggerEn = true;
    return true;
  }

  return false;
}

static void AntiPryingPinConfiguration(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ModeCfg(ANTI_PRYING_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(ANTI_PRYING_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOA_ModeCfg(ANTI_PRYING_PIN, GPIO_ModeIN_PU);
  GPIOA_ITModeCfg(ANTI_PRYING_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_A_IRQn);
#endif

  PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
  AddIrqNewTable(&AntiPryingIrqContorlNode, AntiPryingSensorIrqCallback);
}

static bool AntiPryingEventHandler(void)
{
  BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);

  if (ReadAntiPryingSensorPinLevel() != true)
  {
    switch (AntiPryingBitStatus.AntiPryingHintStep)
    {
    case AUTI_PICK_STEP_ALARM:
    {
      if (AntiPryingBitStatus.AccumulatedPromptCount >= (uint8_t)(60 / ANTI_PRYING_ALARM_TIP_INTERVAL))
      {
        PRINT("[alarm]: auti tip reach the rated number of prompts.\r\n");

        AntiPryingBitStatus.AccumulatedPromptCount = 0;
        AntiPryingBitStatus.AntiPryingHintStep = AUTI_PICK_STEP_LISTER;

        uint32_t IntervalTime = BasicGetAntiSkidDetetionInterval() * 60;
        UpdateAutiPickAlarmTipInterval(IntervalTime);
      }
      else
      {
        AntiPryingBitStatus.AccumulatedPromptCount++;

        BasicAntiSkidTiggerAlarmState();
        UpdateAutiPickAlarmTipInterval(ANTI_PRYING_ALARM_TIP_INTERVAL);
      }
    }
    break;

    case AUTI_PICK_STEP_LISTER:
    {
      PRINT("[alarm]: reset auti tip count.\r\n");

      AntiPryingBitStatus.AntiPryingHintStep = AUTI_PICK_STEP_ALARM;
      UpdateAutiPickAlarmTipInterval(1);
    }
    break;

    default:
    {
      if (BasicGetAntiSkidDetetionAlarmEn() == true)
      {
        PRINT("[alarm]: door is prying.\r\n");

        AntiPryingBitStatus.AntiPryingAlarmTipEn = true;
        AntiPryingBitStatus.AntiPryingHintStep = AUTI_PICK_STEP_ALARM;

        AntiPryingSensorSwitchIrqPinLevel(true);
        BasicWriteAutiPickAlarmTiggerStatusLogFile(true);

        UpdateAutiPickAlarmTipInterval(1);
        SetAutiPickAlarmTipFunctionBit(true);
      }
    }
    break;
    }

    return true;
  }
  else
  {
    PRINT("[alarm]: door is not prying.\r\n");

    SetAutiPickAlarmTipFunctionBit(false);
    AntiPryingSensorSwitchIrqPinLevel(false);

    if (AntiPryingBitStatus.AntiPryingAlarmTipEn == true)
    {
      BasicAntiSkidReturnedToDefaultState();
      BasicWriteAutiPickAlarmTiggerStatusLogFile(false);
    }

    memset(&AntiPryingBitStatus, 0, sizeof(AntiPryingBitStatus_t));
  }

  return false;
}

static void CreateAutiPickTipTask(void)
{
  bool CreateResult = EventAddNewTimedTask(&AutiPickTipNode, 1, TIMED_TASK_HIGH_LEVEL, AntiPryingEventHandler, false);
  PRINT("[info]: create anti-skid detection alarm task result: %d.\r\n", CreateResult);
}

static void SetAutiPickAlarmTipFunctionBit(bool En)
{
  AutiPickTipNode.En = En;
}

static void ResetAutiPickAlarmTipTime(void)
{
  AutiPickTipNode.AccruedTime = 0;
}

void UpdateAutiPickAlarmTipInterval(uint8_t Interval)
{
  AutiPickTipNode.AccruedTime = 0;
  AutiPickTipNode.TriggerTime = Interval;
}

#endif

#if _BEVELED_LATCH_DETECTION_ENABLE_
/**
 * @brief 切换斜舌传感器中断管脚电平
 *
 * @param IrqLevel - 中断管脚电平（true：高电平 false：低电平）
 */
static void ObliqueTongueSensorSwitchIrqPinLevel(bool IrqLevel);

/**
 * @brief 读取斜舌传感器管脚电平
 *
 * @return bool - 管脚电平（true：高电平 false：低电平）
 */
static bool ObliqueTongueSensorGetPinLevel(void);

/**
 * @brief 获取斜舌传感器中断标志位
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool GetObliqueTongueSensorItFlagBit(void);

/**
 * @brief 清除斜舌传感器中断标志位
 *
 */
static void ClearObliqueTongueSensorItFlagBit(void);

/**
 * @brief 使能斜舌传感器中断
 *
 */
static void EnableObliqueTongueSensorIrq(void);

/**
 * @brief 失能斜舌传感器中断
 *
 */
static void DisableObliqueTongueSensorIrq(void);

/**
 * @brief 斜舌中断触发回调
 *
 * @return bool - 中断触发状态（true：触发 false：静止）
 */
static bool ObliqueTongueSensorIrqCallback(void);

/**
 * @brief 斜舌管脚配置
 *
 */
static void ObliqueTonguePinConfiguration(void);

/**
 * @brief 斜舌事件处理方法
 *
 * @return bool - 事件处理标识（true：处理 false：静默）
 */
static bool ObliqueTongueEventHandler(void);

/**
 * @brief 创建假锁提示回调
 *
 */
static void CreateFalseLockTipTask(void);

/**
 * @brief 配置假锁警报提示功能
 *
 * @param En - 功能配置位（true：打开 false：关闭）
 */
static void SetFalseLockAlarmTipFunctionBit(bool En);

/**
 * @brief 重置假锁提示时间
 *
 */
static void ResetFalseLockAlarmTipTime(void);

static TimedTable_t FalseLockTipNode = {0};
static IrqControl_t ObliqueTongueIrqContorlNode = {0};
static ObliqueTongueBitStatus_t ObliqueTongueBitStatus = {0};

static void ObliqueTongueSensorSwitchIrqPinLevel(bool IrqLevel)
{
  ClearObliqueTongueSensorItFlagBit();

#if _BOARD_TYPE_ == _M157_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);

#endif
}

static bool ObliqueTongueSensorGetPinLevel(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  if (GPIOB_ReadPortPin(INCLINED_TONGUE_SENSOR_PIN) == INCLINED_TONGUE_SENSOR_PIN)
    return true;

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOB_ReadPortPin(INCLINED_TONGUE_SENSOR_PIN) == INCLINED_TONGUE_SENSOR_PIN)
    return true;

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  if (GPIOB_ReadPortPin(INCLINED_TONGUE_SENSOR_PIN) == INCLINED_TONGUE_SENSOR_PIN)
    return true;
#endif

  return false;
}

static bool GetObliqueTongueSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  if (GPIOB_ReadITFlagBit(INCLINED_TONGUE_SENSOR_PIN) == INCLINED_TONGUE_SENSOR_PIN)
    return true;

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOB_ReadITFlagBit(INCLINED_TONGUE_SENSOR_PIN) == INCLINED_TONGUE_SENSOR_PIN)
    return true;

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  if (GPIOB_ReadITFlagBit(INCLINED_TONGUE_SENSOR_PIN) == INCLINED_TONGUE_SENSOR_PIN)
    return true;
#endif

  return false;
}

static void ClearObliqueTongueSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);
#endif
}

static void EnableObliqueTongueSensorIrq(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  R16_PB_INT_EN |= INCLINED_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PB_INT_EN |= INCLINED_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  R16_PB_INT_EN |= INCLINED_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);
#endif
}

static void DisableObliqueTongueSensorIrq(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  R16_PB_INT_EN &= ~INCLINED_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PB_INT_EN &= ~INCLINED_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  R16_PB_INT_EN &= ~INCLINED_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(INCLINED_TONGUE_SENSOR_PIN);
#endif
}

static bool ObliqueTongueSensorIrqCallback(void)
{
  if (GetObliqueTongueSensorItFlagBit() == true)
  {
    ClearObliqueTongueSensorItFlagBit();

    ObliqueTongueBitStatus.ObliqueTongueTiggerEn = true;
    return true;
  }

  return false;
}

static void ObliqueTonguePinConfiguration(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(INCLINED_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);
#endif

  PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
  AddIrqNewTable(&ObliqueTongueIrqContorlNode, ObliqueTongueSensorIrqCallback);
}

static bool ObliqueTongueEventHandler(void)
{
  BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);

  if (ObliqueTongueSensorGetPinLevel() != true)
  {
    switch (ObliqueTongueBitStatus.ObliqueLockHintStatus)
    {
    case OBLIQUE_STEP_LISTER:
    {
      if (ObliqueTongueBitStatus.ObliqueTongueTiggerCount == 0)
      {
        PRINT("[alarm]: false lock has been triggered.\r\n");

        ObliqueTongueBitStatus.FalseLockTipEn = true;
        ObliqueTongueBitStatus.FalseLockTipCount = 0;
        ObliqueTongueBitStatus.ObliqueLockHintStatus = OBLIQUE_STEP_ALARM;

        BasicWriteFalseLockAlarmTiggerStatusLogFile(true);

        if (BasicGetUnlockTaskIsAction() == true)
        {
          ObliqueTongueBitStatus.ObliqueTongueAlarmTipEn = false;
          BasicBeveledLatchReset();
        }
      }
      else
      {
        ObliqueTongueBitStatus.ObliqueTongueTiggerCount--;
      }
    }
    break;

    case OBLIQUE_STEP_ALARM:
    {
      if (ObliqueTongueBitStatus.FalseLockTipCount % SENSOR_FALSE_LOCK_ALARM_TIME == 0)
      {
        BasicFalseTiggerAlarmState();
      }

      ObliqueTongueBitStatus.FalseLockTipCount++;
      if (ObliqueTongueBitStatus.FalseLockTipCount >= 60)
      {
        ObliqueTongueBitStatus.FalseLockTipCount = 0;
        ObliqueTongueBitStatus.ObliqueLockHintStatus = OBLIQUE_STEP_WAIT;
      }
    }
    break;

    case OBLIQUE_STEP_WAIT:
    {
      ObliqueTongueBitStatus.FalseLockTipCount++;
      if (ObliqueTongueBitStatus.FalseLockTipCount >= (BasicGetFalseLockDetcetionInterval() * 60))
      {
        ObliqueTongueBitStatus.FalseLockTipCount = 0;
        ObliqueTongueBitStatus.ObliqueLockHintStatus = OBLIQUE_STEP_ALARM;
      }
    }
    break;

    default:
    {
      if (BasicGetDoorLeftAjarAlarmEn() == true)
      {
        ObliqueTongueBitStatus.ObliqueTongueAlarmTipEn = true;
        ObliqueTongueBitStatus.ObliqueLockHintStatus = OBLIQUE_STEP_LISTER;
        ObliqueTongueBitStatus.ObliqueTongueTiggerCount = (BasicGetUnlockTaskIsAction() == true) ? SENSOR_UNLOCK_AFTER_WAIT_TIME : SENSOR_FALSE_LOCK_ALARM_TIME;

        SetFalseLockAlarmTipFunctionBit(true);
        ObliqueTongueSensorSwitchIrqPinLevel(true);
        PRINT("[alarm]: oblique lock has been triggered.\r\n");
      }
    }
    break;
    }

    return true;
  }
  else
  {
    PRINT("[alarm]: oblique lock has returned to the default state.\r\n");

    SetFalseLockAlarmTipFunctionBit(false);
    ObliqueTongueSensorSwitchIrqPinLevel(false);

    if (ObliqueTongueBitStatus.FalseLockTipEn == true)
    {
      BasicFalseReturnedToDefaultState();
      BasicWriteFalseLockAlarmTiggerStatusLogFile(false);
    }

    if (BasicGetUnlockTaskIsAction() == true)
    {
      BasicBeveledLatchReset();
    }

    memset(&ObliqueTongueBitStatus, 0, sizeof(ObliqueTongueBitStatus_t));
  }

  return false;
}

static void CreateFalseLockTipTask(void)
{
  bool CreateResult = EventAddNewTimedTask(&FalseLockTipNode, 1, TIMED_TASK_HIGH_LEVEL, ObliqueTongueEventHandler, false);
  PRINT("[info]: create false lock alarm task result: %d.\r\n", CreateResult);
}

static void SetFalseLockAlarmTipFunctionBit(bool En)
{
  FalseLockTipNode.En = En;
}

static void ResetFalseLockAlarmTipTime(void)
{
  FalseLockTipNode.AccruedTime = 0;
}

void UpdateFalseLockAlarmTipInterval(uint8_t Interval)
{
  FalseLockTipNode.AccruedTime = 0;
  FalseLockTipNode.TriggerTime = Interval;
}
#endif

#if _LOCK_LATCH_DETECTION_ENABLE_

/**
 * @brief 切换锁舌传感器中断管脚电平
 *
 * @param IrqLevel - 中断管脚电平（true：高电平 false：低电平）
 */
static void HeadTongueSensorSwitchIrqPinLevel(bool IrqLevel);

/**
 * @brief 读取锁舌传感器管脚电平
 *
 * @return bool - 管脚电平（true：高电平 false：低电平）
 */
static bool HeadTongueSensorGetPinLevel(void);

/**
 * @brief 获取锁舌传感器中断标志位
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool GetHeadTongueSensorItFlagBit(void);

/**
 * @brief 清除锁舌传感器中断标志
 *
 */
static void ClearHeadTongueSensorItFlagBit(void);

/**
 * @brief 使能锁舌传感器中断
 *
 */
static void EnableHeadTongueSensorIrq(void);

/**
 * @brief 失能锁舌传感器中断
 *
 */
static void DisableHeadTongueSensorIrq(void);

/**
 * @brief 锁舌中断回调
 *
 * @return bool - 中断触发状态（true：触发 false：静止）
 */
static bool HeadTongueSensorIrqCallback(void);

/**
 * @brief 锁舌管脚配置
 *
 */
static void HeadTonguePinConfiguration(void);

/**
 * @brief 锁舌事件处理方法
 *
 * @return bool - 事件处理标识（true：处理 false：静默）
 */
static bool HeadTongueEventHandler(void);

/**
 * @brief 创建钥匙插入提示回调
 *
 */
static void CreateKeyInstallTipTask(void);

/**
 * @brief 配置钥匙插入警报提示功能
 *
 * @param En - 功能配置位（true：打开 false：关闭）
 */
static void SetKeyInstallAlarmTipFunction(bool En);

/**
 * @brief 重置钥匙插入提示时间
 *
 */
static void ResetKeyInstallAlarmTipTime(void);

static TimedTable_t KeyInstallTipNode = {0};
static IrqControl_t HeadTongueIrqContorlNode = {0};
static HeadTongueBitStatus_t HeadTongueBitStatus = {0};

static void HeadTongueSensorSwitchIrqPinLevel(bool IrqLevel)
{
  ClearHeadTongueSensorItFlagBit();

#if _BOARD_TYPE_ == _M157_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_FallEdge);
#endif
}

static bool HeadTongueSensorGetPinLevel(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  if (GPIOB_ReadPortPin(LOCK_HEAD_SENSOR_PIN) == LOCK_HEAD_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOB_ReadPortPin(LOCK_HEAD_SENSOR_PIN) == LOCK_HEAD_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  if (GPIOB_ReadPortPin(LOCK_HEAD_SENSOR_PIN) == LOCK_HEAD_SENSOR_PIN)
#endif
    return true;

  return false;
}

static bool GetHeadTongueSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  if (GPIOB_ReadITFlagBit(LOCK_HEAD_SENSOR_PIN) == LOCK_HEAD_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOB_ReadITFlagBit(LOCK_HEAD_SENSOR_PIN) == LOCK_HEAD_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  if (GPIOB_ReadITFlagBit(LOCK_HEAD_SENSOR_PIN) == LOCK_HEAD_SENSOR_PIN)
#endif
    return true;

  return false;
}

static void ClearHeadTongueSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#endif
}

static void EnableHeadTongueSensorIrq(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  R16_PB_INT_EN |= LOCK_HEAD_SENSOR_PIN;
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PB_INT_EN |= LOCK_HEAD_SENSOR_PIN;
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  R16_PB_INT_EN |= LOCK_HEAD_SENSOR_PIN;
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);
#endif
}

static void DisableHeadTongueSensorIrq(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  R16_PB_INT_EN &= ~LOCK_HEAD_SENSOR_PIN;
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PB_INT_EN &= ~LOCK_HEAD_SENSOR_PIN;
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  R16_PB_INT_EN &= ~LOCK_HEAD_SENSOR_PIN;
  GPIOB_ClearITFlagBit(LOCK_HEAD_SENSOR_PIN);
#endif
}

static bool HeadTongueSensorIrqCallback(void)
{
  if (GetHeadTongueSensorItFlagBit() == true)
  {
    ClearHeadTongueSensorItFlagBit();

    HeadTongueBitStatus.HeadTongueTiggerEn = true;
    return true;
  }

  return false;
}

static void HeadTonguePinConfiguration(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(LOCK_HEAD_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);
#endif

  PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
  AddIrqNewTable(&HeadTongueIrqContorlNode, HeadTongueSensorIrqCallback);
}

static bool HeadTongueEventHandler(void)
{
  BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);

  if (HeadTongueSensorGetPinLevel() != true)
  {
    BasicKeyInsert();

    if (HeadTongueBitStatus.HeadTongueAlarmTipEn != true)
    {
      PRINT("[alarm]: key install.\r\n");

      SetKeyInstallAlarmTipFunction(true);
      HeadTongueSensorSwitchIrqPinLevel(true);
      BasicWriteKeyedInTiggerStatusLogFile(true);
      HeadTongueBitStatus.HeadTongueAlarmTipEn = true;

#if _LOCK_LATCH_DETECTION_ENABLE_
      SetFalseLockAlarmTipFunctionBit(false);
      ObliqueTongueSensorSwitchIrqPinLevel(false);
      memset(&ObliqueTongueBitStatus, 0, sizeof(ObliqueTongueBitStatus_t));
#endif
    }
    else
    {
      if (HeadTongueBitStatus.HeadTongueTiggerCount >= KEY_RESET_WAIT_TIME)
      {
        PRINT("[alarm]: key tigger factory reset.\r\n");

        if (BasicExecuteFactorySetting() == true)
        {
          DisableHeadTongueSensorIrq();
          SetKeyInstallAlarmTipFunction(false);
          BasicWriteKeyedInTiggerStatusLogFile(false);
          memset(&HeadTongueBitStatus, 0, sizeof(HeadTongueBitStatus_t));
        }
        else
        {
          HeadTongueBitStatus.HeadTongueTiggerCount = 0;
        }
      }
      else
      {
        if (BasicGetTheKeyToResetEn() == true)
        {
          HeadTongueBitStatus.HeadTongueTiggerCount++;
        }
      }
    }

    return true;
  }
  else
  {
    PRINT("[alarm]: key remove.\r\n");

    SetKeyInstallAlarmTipFunction(false);
    HeadTongueSensorSwitchIrqPinLevel(false);

    if (HeadTongueBitStatus.HeadTongueAlarmTipEn == true)
    {
      BasicWriteKeyedInTiggerStatusLogFile(false);
      memset(&HeadTongueBitStatus, 0, sizeof(HeadTongueBitStatus_t));
    }
  }

  return false;
}

static void CreateKeyInstallTipTask(void)
{
  bool CreateResult = EventAddNewTimedTask(&KeyInstallTipNode, 2, TIMED_TASK_HIGH_LEVEL, HeadTongueEventHandler, false);
  PRINT("[info]: create key install alarm task result: %d.\r\n", CreateResult);
}

static void SetKeyInstallAlarmTipFunction(bool En)
{
  KeyInstallTipNode.En = En;
}

static void ResetKeyInstallAlarmTipTime(void)
{
  KeyInstallTipNode.AccruedTime = 0;
}

void UpdateKeyInstallAlarmTipInterval(uint8_t Interval)
{
  KeyInstallTipNode.TriggerTime = Interval;
}
#endif

#if _SQUARE_LATCH_DETECTION_ENABLE_
/**
 * @brief 切换方舌传感器中断管脚电平
 *
 * @param IrqLevel - 中断管脚电平（true：高电平 false：低电平）
 */
static void SquareTongueSensorSwitchIrqPinLevel(bool IrqLevel);

/**
 * @brief 读取方舌传感器管脚电平
 *
 * @return bool - 管脚电平（true：高电平 false：低电平）
 */
static bool SquareTongueSensorGetPinLevel(void);

/**
 * @brief 获取方舌传感器中断标志位
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool GetSquareTongueSensorItFlagBit(void);

/**
 * @brief 清除方舌传感器中断标志位
 *
 */
static void ClearSquareTongueSensorItFlagBit(void);

/**
 * @brief 使能方舌传感器中断
 *
 */
static void EnableSquareTongueSensorIrq(void);

/**
 * @brief 失能方舌传感器中断
 *
 */
static void DisableSquareTongueSensorIrq(void);

/**
 * @brief 方舌中断触发回调
 *
 * @return bool - 中断触发状态（true：触发 false：静止）
 */
static bool SquareTongueSensorIrqCallback(void);

/**
 * @brief 方舌管脚配置
 *
 */
static void SquareTonguePinConfiguration(void);

/**
 * @brief 创建反锁提示回调
 *
 */
static void CreateDoubleLockTipTask(void);

/**
 * @brief 配置反锁警报提示功能
 *
 * @param En - 功能配置位（true：打开 false：关闭）
 */
static void SetDoubleLockAlarmTipFunctionBit(bool En);

/**
 * @brief 重置反锁提示时间
 *
 */
static void ResetDoubleLockAlarmTipTime(void);

/**
 * @brief 方舌事件处理方法
 *
 */
static bool SquareTongueEventHandler(void);

static TimedTable_t DoubleLockTipNode = {0};
static IrqControl_t SquareTongueIrqContorlNode = {0};
static SquareTongueBitStatus_t SquareTongueBitStatus = {0};

static void SquareTongueSensorSwitchIrqPinLevel(bool IrqLevel)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
#endif
}

static bool SquareTongueSensorGetPinLevel(void)
{
  ClearSquareTongueSensorItFlagBit();

#if _BOARD_TYPE_ == _M157_A_BOARD_
  if (GPIOB_ReadPortPin(SQUARE_TONGUE_SENSOR_PIN) == SQUARE_TONGUE_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOB_ReadPortPin(SQUARE_TONGUE_SENSOR_PIN) == SQUARE_TONGUE_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  if (GPIOB_ReadPortPin(SQUARE_TONGUE_SENSOR_PIN) == SQUARE_TONGUE_SENSOR_PIN)
#endif
    return true;

  return false;
}

static bool GetSquareTongueSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  if (GPIOB_ReadITFlagBit(SQUARE_TONGUE_SENSOR_PIN) == SQUARE_TONGUE_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  if (GPIOB_ReadITFlagBit(SQUARE_TONGUE_SENSOR_PIN) == SQUARE_TONGUE_SENSOR_PIN)

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  if (GPIOB_ReadITFlagBit(SQUARE_TONGUE_SENSOR_PIN) == SQUARE_TONGUE_SENSOR_PIN)
#endif
    return true;

  return false;
}

static void ClearSquareTongueSensorItFlagBit(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);
#endif
}

static void EnableSquareTongueSensorIrq(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);
  R16_PB_INT_EN |= SQUARE_TONGUE_SENSOR_PIN;

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);
  R16_PB_INT_EN |= SQUARE_TONGUE_SENSOR_PIN;

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);
  R16_PB_INT_EN |= SQUARE_TONGUE_SENSOR_PIN;
#endif
}

static void DisableSquareTongueSensorIrq(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);
  R16_PB_INT_EN &= ~SQUARE_TONGUE_SENSOR_PIN;

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  R16_PB_INT_EN &= ~SQUARE_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  R16_PB_INT_EN &= ~SQUARE_TONGUE_SENSOR_PIN;
  GPIOB_ClearITFlagBit(SQUARE_TONGUE_SENSOR_PIN);
#endif
}

static bool SquareTongueSensorIrqCallback(void)
{
  if (GetSquareTongueSensorItFlagBit() == true)
  {
    ClearSquareTongueSensorItFlagBit();

    SquareTongueBitStatus.SquareTongueTiggerEn = true;
    return true;
  }

  return false;
}

static void SquareTonguePinConfiguration(void)
{
#if _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(SQUARE_TONGUE_SENSOR_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);
#endif

  PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
  AddIrqNewTable(&SquareTongueIrqContorlNode, SquareTongueSensorIrqCallback);
}

static bool SquareTongueEventHandler(void)
{
  BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);

  if (SquareTongueSensorGetPinLevel() != true)
  {
    if (BasicGetLockedInSignalOutputEn() == true)
    {
      if (SquareTongueBitStatus.SquareTongueAlarmTipEn != true)
      {
        SquareTongueBitStatus.SquareTongueAlarmTipEn = true;
        PRINT("[alarm]: double lock has been triggered.\r\n");

        SetDoubleLockAlarmTipFunctionBit(true);
        SquareTongueSensorSwitchIrqPinLevel(true);
        BasicWriteDoubleLockTiggerStatusLogFile(true);
        UpdateDoubleLockAlarmTipInterval(BasicGetLockedInReminderInterval());
      }

      BasicLockedInTigger();
    }

    return true;
  }
  else
  {
    SetDoubleLockAlarmTipFunctionBit(false);
    SquareTongueSensorSwitchIrqPinLevel(false);

    if (SquareTongueBitStatus.SquareTongueAlarmTipEn == true)
    {
      PRINT("[alarm]: double lock has returned to the default state.\r\n");

      BasicLockInRecovery();
      UpdateDoubleLockAlarmTipInterval(1);
      BasicWriteDoubleLockTiggerStatusLogFile(false);
    }

    memset(&SquareTongueBitStatus, 0, sizeof(SquareTongueBitStatus_t));
  }

  return false;
}

static void CreateDoubleLockTipTask(void)
{
  bool CreateResult = EventAddNewTimedTask(&DoubleLockTipNode, 1, TIMED_TASK_HIGH_LEVEL, SquareTongueEventHandler, false);
  PRINT("[info]: create double lock alarm task result: %d.\r\n", CreateResult);
}

static void SetDoubleLockAlarmTipFunctionBit(bool En)
{
  DoubleLockTipNode.En = En;
}

static void ResetDoubleLockAlarmTipTime(void)
{
  DoubleLockTipNode.AccruedTime = 0;
}

void UpdateDoubleLockAlarmTipInterval(uint8_t Interval)
{
  DoubleLockTipNode.AccruedTime = 0;
  DoubleLockTipNode.TriggerTime = Interval;
}
#endif

#if _EXIT_BUTTON_DETECTION_ENABLE_

/**
 * @brief 切换出门按钮中断管脚电平
 *
 * @param IrqLevel - 中断管脚电平（true：高电平 false：低电平）
 */
static void ExitButtonSwitchIrqPinLevel(bool IrqLevel);

/**
 * @brief 获取出门按钮管脚电平
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool ExitButtonGetPinLevel(void);

/**
 * @brief 获取出门按键中断标志位
 *
 * @return bool - 中断触发标志位（true：触发 false：静默）
 */
static bool GetExitButtonItFlagBit(void);

/**
 * @brief 清除出门按键中断标志位
 *
 */
static void ClearExitButtonItFlagBit(void);

/**
 * @brief 使能出门按键中断
 *
 */
static void EnableExitButtonIrq(void);

/**
 * @brief 失能出门按键中断
 *
 */
static void DisableExitButtonIrq(void);

/**
 * @brief 出门按键中断回调
 *
 * @return bool - 中断触发状态（true：触发 false：静止）
 */
static bool ExitButtonIrqCallback(void);

/**
 * @brief 出门按键管脚配置
 *
 */
static void ExitButtonPinConfiguration(void);

/**
 * @brief 出门按键事件处理
 *
 * @return bool - 事件处理标识（true：处理 false：静默）
 */
static bool ExitButtonEventHandler(void);

static IrqControl_t ExitButtonIrqContorlNode = {0};
static ExitButtonBitStatus_t ExitButtonBitStatus = {0};

static void ExitButtonSwitchIrqPinLevel(bool IrqLevel)
{
  ClearExitButtonItFlagBit();

#if _BOARD_TYPE_ == _DA01_A_BOARD_
  (IrqLevel == true) ? GPIOB_ITModeCfg(EXIT_BUTTOM_PIN, GPIO_ITMode_RiseEdge) : GPIOB_ITModeCfg(EXIT_BUTTOM_PIN, GPIO_ITMode_FallEdge);
#endif
}

static bool ExitButtonGetPinLevel(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  if (GPIOB_ReadPortPin(EXIT_BUTTOM_PIN) == EXIT_BUTTOM_PIN)
    return true;
#endif

  return false;
}

static bool GetExitButtonItFlagBit(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  if (GPIOB_ReadITFlagBit(EXIT_BUTTOM_PIN) == EXIT_BUTTOM_PIN)
    return true;
#endif

  return false;
}

static void ClearExitButtonItFlagBit(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  GPIOB_ClearITFlagBit(EXIT_BUTTOM_PIN);
#endif
}

static void EnableExitButtonIrq(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  R16_PB_INT_EN |= EXIT_BUTTOM_PIN;
  GPIOB_ClearITFlagBit(EXIT_BUTTOM_PIN);
#endif
}

static void DisableExitButtonIrq(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  R16_PB_INT_EN &= ~EXIT_BUTTOM_PIN;
  GPIOB_ClearITFlagBit(EXIT_BUTTOM_PIN);
#endif
}

static bool ExitButtonIrqCallback(void)
{
  if (GetExitButtonItFlagBit() == true)
  {
    ClearExitButtonItFlagBit();

    ExitButtonBitStatus.ExitButtonTiggerEn = true;
    return true;
  }

  return false;
}

static void ExitButtonPinConfiguration(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  GPIOB_ModeCfg(EXIT_BUTTOM_PIN, GPIO_ModeIN_PU);
  GPIOB_ITModeCfg(EXIT_BUTTOM_PIN, GPIO_ITMode_FallEdge);
  PFIC_EnableIRQ(GPIO_B_IRQn);
#endif

  PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
  AddIrqNewTable(&ExitButtonIrqContorlNode, ExitButtonIrqCallback);
}

static bool ExitButtonEventHandler(void)
{
  return EventExecuteUnlockTask(LOG_EXIT_BUTTON, NULL, 0, DOOR_ACTION_UNLOCK);
}
#endif

static void SensorEventHandlerCallback(void)
{
#if _HALL_SENSOR_ENABLE_
  if (HallSensorBitStatus.HallSensorTiggerEn == true)
  {
    HallSensorBitStatus.HallSensorTiggerEn = false;

    BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);
    if (HallGetPinLevel() != true)
    {
      HallEventHandler();
    }
  }
#endif

#if _ANTI_SKID_DETECTION_ENABLE_
  if (AntiPryingBitStatus.AntiPryingTiggerEn == true)
  {
    AntiPryingBitStatus.AntiPryingTiggerEn = false;

    BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);
    if (ReadAntiPryingSensorPinLevel() != true)
    {
      AntiPryingEventHandler();
    }
  }
#endif

#if _LOCK_LATCH_DETECTION_ENABLE_
  if (HeadTongueBitStatus.HeadTongueTiggerEn == true)
  {
    HeadTongueBitStatus.HeadTongueTiggerEn = false;
    HeadTongueEventHandler();
  }
#endif

#if _BEVELED_LATCH_DETECTION_ENABLE_
  if (ObliqueTongueBitStatus.ObliqueTongueTiggerEn == true)
  {
    ObliqueTongueBitStatus.ObliqueTongueTiggerEn = false;
    ObliqueTongueEventHandler();
  }
#endif

#if _SQUARE_LATCH_DETECTION_ENABLE_
  if (SquareTongueBitStatus.SquareTongueTiggerEn == true)
  {
    SquareTongueBitStatus.SquareTongueTiggerEn = false;
    SquareTongueEventHandler();
  }
#endif

#if _EXIT_BUTTON_DETECTION_ENABLE_
  if (ExitButtonBitStatus.ExitButtonTiggerEn == true)
  {
    ExitButtonBitStatus.ExitButtonTiggerEn = false;

    BasicDelayMs(SENSOR_DEBOUNCE_WAIT_TIME);
    if (ExitButtonGetPinLevel() != true)
    {
      ExitButtonEventHandler();
    }
  }
#endif
}

bool GetHeadTongueTiggerEn(void)
{
#if _LOCK_LATCH_DETECTION_ENABLE_
  return HeadTongueBitStatus.HeadTongueAlarmTipEn;

#else
  return false;
#endif
}

bool GetFlaseLockAlarmEn(void)
{
#if _BEVELED_LATCH_DETECTION_ENABLE_
  return ObliqueTongueBitStatus.FalseLockTipEn;

#else
  return false;
#endif
}

bool GetObliqueLockAlarmEn(void)
{
#if _BEVELED_LATCH_DETECTION_ENABLE_
  return ObliqueTongueBitStatus.ObliqueTongueAlarmTipEn;

#else
  return false;
#endif
}

bool GetAntiPickingAlarmEn(void)
{
#if _ANTI_SKID_DETECTION_ENABLE_
  return AntiPryingBitStatus.AntiPryingAlarmTipEn;

#else
  return false;
#endif
}

bool GetAntiLockSignalTiggerEn(void)
{
#if _SQUARE_LATCH_DETECTION_ENABLE_
  return SquareTongueBitStatus.SquareTongueAlarmTipEn;

#else
  return false;
#endif
}

void DisableAllSensorInSoucre(void)
{
#if _HALL_SENSOR_ENABLE_
  HallDisableIrq();
#endif

#if _ANTI_SKID_DETECTION_ENABLE_
  DiableAntiPryingIrq();
  SetAutiPickAlarmTipFunctionBit(false);
#endif

#if _LOCK_LATCH_DETECTION_ENABLE_
  DisableHeadTongueSensorIrq();
  SetKeyInstallAlarmTipFunction(false);
#endif

#if _BEVELED_LATCH_DETECTION_ENABLE_
  DisableObliqueTongueSensorIrq();
  SetFalseLockAlarmTipFunctionBit(false);
#endif

#if _SQUARE_LATCH_DETECTION_ENABLE_
  DisableSquareTongueSensorIrq();
  SetDoubleLockAlarmTipFunctionBit(false);
#endif

#if _EXIT_BUTTON_DETECTION_ENABLE_
  DisableExitButtonIrq();
#endif
}

void EnableAllSensorInSoucre(void)
{
#if _HALL_SENSOR_ENABLE_
  HallEnableIrq();
#endif

#if _ANTI_SKID_DETECTION_ENABLE_
  EnableAntiPryingSensorIrq();
  SetAutiPickAlarmTipFunctionBit(true);
#endif

#if _LOCK_LATCH_DETECTION_ENABLE_
  EnableHeadTongueSensorIrq();
  SetKeyInstallAlarmTipFunction(true);
#endif

#if _SQUARE_LATCH_DETECTION_ENABLE_
  EnableSquareTongueSensorIrq();
  SetDoubleLockAlarmTipFunctionBit(true);
#endif

#if _BEVELED_LATCH_DETECTION_ENABLE_
  EnableObliqueTongueSensorIrq();
  SetFalseLockAlarmTipFunctionBit(true);
#endif

#if _EXIT_BUTTON_DETECTION_ENABLE_
  EnableExitButtonIrq();
#endif
}

void SensorBoardInitialisation(void)
{
#if _ANTI_SKID_DETECTION_ENABLE_
  CreateAutiPickTipTask();
  AntiPryingPinConfiguration();
#endif

#if _LOCK_LATCH_DETECTION_ENABLE_
  CreateKeyInstallTipTask();
  HeadTonguePinConfiguration();
#endif

#if _BEVELED_LATCH_DETECTION_ENABLE_
  CreateFalseLockTipTask();
  ObliqueTonguePinConfiguration();
#endif

#if _SQUARE_LATCH_DETECTION_ENABLE_
  CreateDoubleLockTipTask();
  SquareTonguePinConfiguration();
#endif

  EventAddNewEventHandler(&SensorEventHandlerNode, SensorEventHandlerCallback);
}
